package ai.people.netmon.auth.service;

import ai.people.core.security.entity.AuthenticationUser;
import ai.people.netmon.framework.constant.OAuth2Constant;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author yuanqinglong
 * @date 2022/2/11 11:45
 */
@Component
public class JwtTokenEnhancer implements TokenEnhancer {


    /**
     * 增强
     * 对当前客户端提供自定义的用户数据返回,用于去做OAuth2身份认证
     * <p>
     * OAuth2AccessToken: 它的实现类只有一个叫做 {@link DefaultOAuth2AccessToken} 中的 setAdditionalInformation()方法
     * 他的方法主要是以下作用:
     * 令牌授予者想要添加到令牌的附加信息，例如支持新的令牌类型。如果映射中的值是原始值
     * 则远程通信将始终有效。使用地图（如果需要，嵌套）或由 Jackson 明确序列化的东西也应该是安全的。
     *
     * @param accessToken    oauth2的token
     * @param authentication authentication.getPrincipal()获取当前登录的用户信息
     * @return {@link OAuth2AccessToken}
     */
    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        /*
         * 此处直接强转即可。因为我们知道当前的这个登录用户就是我们自定义的用户对象
         */
        AuthenticationUser jwtUser = (AuthenticationUser) authentication.getPrincipal();
        if (jwtUser != null) {
            Map<String, Object> additionMessage = new LinkedHashMap<>();
            //map.put("userInfo", JSONUtils.beanToJson(jwtUser));
            additionMessage.put(OAuth2Constant.MATE_USER_ID, String.valueOf(jwtUser.getUserId()));
            additionMessage.put(OAuth2Constant.MATE_USER_NAME, jwtUser.getUsername());
            additionMessage.put(OAuth2Constant.JOIN_MAX_COUNT, jwtUser.getJoinMaxCount());
            additionMessage.put(OAuth2Constant.PLACE, jwtUser.getPlace());
            additionMessage.put(OAuth2Constant.PHONE, jwtUser.getUserPhone());
            additionMessage.put(OAuth2Constant.ACCESSIBLE_SOURCE, jwtUser.getAccessibleSource());
            //additionMessage.put(OAuth2Constant.MATE_ROLE_ID, String.valueOf(jwtUser.getUserRoleId()));
            /*
             * 这样我们的accessToken就可以进行扩展信息了。然后将其配置到授权服务器中。{@link com.qycq.oauth.security.AuthorizationServerConfig}
             */
            ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionMessage);
        }
        return accessToken;
    }
}
